1 : <?php
2 : /*--------------------------------------------------------------------------+
3 : This file is part of eStudy.
4 : ressourcen/classes/archiver/class.zipprovider.inc.php
5 : - Module group: File Manager
6 : - Description: Class "ZipProvider"
7 : - Version: $Id: class.zipprovider.inc.php 3069 2009-11-25 16:55:52Z nilsbraden $
8 : - Author(s): Bjoern Kasteleiner <bjoern.kasteleiner@mni.fh-giessen.de>
9 : +---------------------------------------------------------------------------+
10 : This program is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU General Public License
12 : as published by the Free Software Foundation; either version 2
13 : of the License, or any later version.
14 : +---------------------------------------------------------------------------+
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 : +--------------------------------------------------------------------------*/
23 :
24 : if (!defined("PATH_TO_ROOT")) {
25 : define("PATH_TO_ROOT", "../../../");
26 : }
27 :
28 : require_once (PATH_TO_ROOT."ressourcen/classes/filemanager/class.file.inc.php");
29 : require_once (PATH_TO_ROOT."ressourcen/classes/filemanager/class.folder.inc.php");
30 : require_once (PATH_TO_ROOT."ressourcen/classes/archiver/class.zipvisitor.inc.php");
31 : require_once (PATH_TO_ROOT."ressourcen/classes/archiver/interface.archiveprovider.inc.php");
32 : require_once (PATH_TO_ROOT."ressourcen/classes/archiver/class.archiverexception.inc.php");
33 :
34 :
35 : /**
36 : * Provides a zip archive of a folder.
37 : *
38 : * @author Bjoern Kasteleiner <bjoern.kasteleiner@mni.fh-giessen.de>
39 : * @version $Id: class.zipprovider.inc.php 3069 2009-11-25 16:55:52Z nilsbraden $
40 : */
41 : class ZipProvider implements ArchiveProvider {
42 : private $folder;
43 : private $recursion;
44 : private $tempFile;
45 :
46 : /**
47 : * Constructor for ZipProvider class.
48 : *
49 : * Basic checks of incomming values.
50 : * If $tempFile is null, the upload_path is used to
51 : * create a temporary file for zip creation.
52 : *
53 : * @param Folder $folder Folder
54 : * @param Boolean $recursion Recursion flag (Default: False)
55 : * @param String $tempFile Temporary filepath (Default: null)
56 : */
57 : public function __construct(Folder $folder, $recursion = FALSE, $tempFile = null) {
58 0 : assert(!is_null($folder));
59 0 : assert($folder instanceof Folder);
60 :
61 0 : global $settings;
62 :
63 0 : $this->folder = $folder;
64 0 : $this->recursion = $recursion;
65 :
66 0 : if (empty($tempFile)) {
67 0 : $basedir = PATH_TO_ROOT.$settings["upload_path"];
68 0 : $basedir .= 'filemanager/courseID/'.$_SESSION['course'];
69 :
70 0 : $tempFile = tempnam($basedir, "archiver");
71 0 : }
72 :
73 0 : $this->tempFile = $tempFile;
74 0 : }
75 :
76 : /**
77 : * Destructor of ZipProvider.
78 : *
79 : * Used to clean up temporary files if needed.
80 : *
81 : */
82 : public function __destruct() {
83 0 : if (file_exists($this->tempFile)) {
84 0 : unlink($this->tempFile);
85 0 : }
86 0 : }
87 :
88 : /**
89 : * Setter for recursion flag.
90 : *
91 : * @param Boolean $recursion Recursion flag
92 : */
93 : public function setRecursion($recursion) {
94 0 : $this->recursion = $recursion;
95 0 : }
96 :
97 : /**
98 : * Getter for recursion flag.
99 : *
100 : * @return Boolean Recursion flag
101 : */
102 : public function getRecursion() {
103 0 : return $this->recursion;
104 : }
105 :
106 : /**
107 : * Setter for temporary file.
108 : *
109 : * @param String $tempFile Temporary filepath
110 : */
111 : public function setTempFile($tempFile) {
112 0 : $this->tempFile = $tempFile;
113 0 : }
114 :
115 : /**
116 : * Getter for temporary file.
117 : *
118 : * @return String Temporary filepath
119 : */
120 : public function getTempFile() {
121 0 : return $this->tempFile;
122 : }
123 :
124 : /**
125 : * Setter for archiving folder.
126 : *
127 : * @param Folder $folder Folder
128 : */
129 : public function setFolder(Folder $folder) {
130 0 : $this->folder = $folder;
131 0 : }
132 :
133 : /**
134 : * Getter for archiving folder.
135 : *
136 : * @return Folder Folder
137 : */
138 : public function getFolder() {
139 0 : return $this->folder;
140 : }
141 :
142 : /**
143 : * Create an archive of the given Folder.
144 : *
145 : * With or without subfolders, depending on recursion flag.
146 : */
147 : public function createArchive() {
148 0 : $zipArchiver = new ZipArchive();
149 0 : if ($zipArchiver->open($this->tempFile, ZipArchive::OVERWRITE) !== TRUE) {
150 0 : throw new ArchiverException("Fehler beim Anlegen des Archivs. ".$this->tempFile);
151 : }
152 :
153 0 : $zipVisitor = new ZipVisitor($zipArchiver, $this->recursion);
154 0 : $this->folder->archiverAccept($zipVisitor);
155 :
156 0 : if ($zipArchiver->status != ZipArchive::ER_OK) {
157 0 : throw new ArchiverException("Fehler beim Erzeugen des Archivs: ".$zipArchiver->status);
158 : }
159 0 : $zipArchiver->close();
160 0 : }
161 :
162 : /**
163 : * Send archive to the client.
164 : *
165 : * Send needed header informations and logging folder
166 : * download and increment folder download count.
167 : */
168 : public function sendArchive() {
169 0 : global $resDB;
170 :
171 0 : if (file_exists($this->tempFile)) {
172 0 : $filename = $resDB->getCourseShortNameByID($this->folder->getCourseID());
173 0 : if ($filename != "") $filename .= "-";
174 0 : $filename .= $this->folder->getLink().".zip";
175 :
176 0 : $this->logFolderDownload($this->folder);
177 :
178 0 : header("Content-Type: application/zip");
179 0 : header("Content-Disposition: attachment; filename=\"".$filename."\"");
180 0 : header("Content-Transfer-Encoding: binary");
181 0 : header("Content-Length: ".filesize($this->tempFile));
182 :
183 0 : readfile($this->tempFile);
184 0 : unlink($this->tempFile);
185 0 : } else {
186 0 : throw new ArchiverException("Bereitgestelltes Zip Archive konnte nicht gefunden werden.");
187 : }
188 0 : }
189 :
190 : /**
191 : * Logging folder download and increment folder download count.
192 : *
193 : * @param Folder $folder Folder
194 : */
195 : private function logFolderDownload(Folder $folder) {
196 0 : global $resDB;
197 :
198 0 : $resDB->logResourceDownload($folder->getID());
199 :
200 0 : $files = $folder->getFiles();
201 0 : foreach ($files as $file) {
202 0 : $resDB->logResourceDownload($file->getID());
203 0 : }
204 :
205 0 : if ($this->recursion) {
206 0 : $subFolders = $folder->getSubFolders();
207 0 : foreach ($subFolders as $subFolder) {
208 0 : $this->logFolderDownload($subFolder);
209 0 : }
210 0 : }
211 0 : }
212 :
213 :
214 : /**
215 : * Check archive filesizes.
216 : *
217 : * Calculate the filesize of the folder and its subfolders.
218 : *
219 : * @param Folder $folder Folder
220 : * @param Boolean $recursion Recursion flag
221 : * @return Integer Size of folder and subfolders
222 : */
223 : public static function checkArchiveSize(Folder $folder, $recursion) {
224 0 : global $resDB;
225 :
226 0 : $size = 0;
227 :
228 0 : $files = $folder->getFiles();
229 0 : foreach ($files as $file) {
230 0 : $size += $file->getSize();
231 0 : }
232 :
233 0 : if ($recursion) {
234 0 : $subFolders = $folder->getSubFolders();
235 0 : foreach ($subFolders as $subFolder) {
236 0 : $size += self::checkArchiveSize($subFolder, $recursion);
237 0 : }
238 0 : }
239 :
240 0 : return $size;
241 : }
242 : }
|